package io.github.flylinran.common.aspect;

import io.github.flylinran.common.annotation.RequestLimit;
import io.github.flylinran.common.exception.RequestLimitException;
import io.github.flylinran.common.utils.HttpContextUtil;
import io.github.flylinran.common.utils.IPUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * 接口访问频率校验器
 */
@Slf4j
@Aspect
@Component
public class RequestLimitAspect {

    private ConcurrentMap<String, Long> map = new ConcurrentHashMap<>();

    @Before(value = "@annotation(io.github.flylinran.common.annotation.RequestLimit)")
    public void doBefore(JoinPoint jp) {
        String ip = IPUtil.getIpAddr(HttpContextUtil.getHttpServletRequest());
        Long aLong = map.get(ip);
        map.put(ip, System.currentTimeMillis());
        if (ObjectUtils.isEmpty(aLong)) {
            return;
        }

        MethodSignature signature = (MethodSignature) jp.getSignature();
        RequestLimit annotation = signature.getMethod().getAnnotation(RequestLimit.class);
        if (System.currentTimeMillis() - aLong < annotation.interval() * 1000)
            throw new RequestLimitException(400, annotation.message());
    }
}